package com.online.music.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.online.music.common.Result;
import com.online.music.entity.po.User;
import com.online.music.entity.vo.SongPageVo;
import com.online.music.entity.vo.SongVo;
import com.online.music.entity.dto.SongDTO;
import com.online.music.entity.po.Lyrics;
import com.online.music.entity.po.Song;
import com.online.music.mapper.LyricsMapper;
import com.online.music.mapper.SongMapper;
import com.online.music.mapper.UserMapper;
import com.online.music.service.ISongService;
import com.online.music.utils.UserContextUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @Author: Leno
 * @Date: 2025-01-31
 * @Description: SongServiceImpl
 */
@Service
@RequiredArgsConstructor
public class SongServiceImpl extends ServiceImpl<SongMapper, Song> implements ISongService {

    private final SongMapper songMapper;

    private final LyricsMapper lyricsMapper;

    private final UserMapper userMapper;

    private final RedisTemplate<String, Object> redisTemplate;

    @Value("${music.report-count:3}")
    private Integer reportCount;

    @Value("${music.report-timeout:1}")
    private Integer reportTimeOut;

    @Override
    public Result<Page<SongPageVo>> findPage(Integer pageNum, Integer pageSize, Song song) {
        Page<Song> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Song> qw = new QueryWrapper<>();

        if (StrUtil.isNotBlank(song.getName())) {
            qw.like("s.name", song.getName());
        }

        if (song.getTypeId() != null) {
            qw.eq("s.type_id", song.getTypeId());
        }

        if (song.getAlbumId() != null) {
            qw.eq("s.album_id", song.getAlbumId());
        }

        if (song.getUserId() != null) {
            qw.eq("s.user_id", song.getUserId());
        }

        if (song.getStatus() != null) {
            qw.eq("s.status", song.getStatus());
        }

        Page<SongPageVo> result = songMapper.findPage(page, qw);
        return Result.success(result);
    }

    @Override
    @Transactional
    public Result<String> deleteBatch(List<Long> ids) {
        // 删除前先判断是否存在...
        removeByIds(ids);
        return Result.successMsg("删除成功");
    }

    @Override
    public Result<Boolean> addOrUpdate(SongDTO songDTO) {

        songDTO.setUserId(UserContextUtil.getUserId());

        if (songDTO.getId() == null) {
            // 添加
            save(songDTO);
            // 添加新的歌词信息
            List<Lyrics> lyricsList = songDTO.getLyrics();
            lyricsList.forEach(lyrics -> lyrics.setSongId(songDTO.getId()));
            lyricsMapper.insert(lyricsList);
        } else {
            // 删除原有的歌词信息
            lyricsMapper.delete(
                    new LambdaQueryWrapper<Lyrics>()
                            .eq(Lyrics::getSongId, songDTO.getId())
            );
            // 添加新的歌词信息
            List<Lyrics> lyricsList = songDTO.getLyrics();
            lyricsList.forEach(lyrics -> lyrics.setSongId(songDTO.getId()));
            lyricsMapper.insert(lyricsList);
            // 更新
            songDTO.setStatus(0);
            songDTO.setBackReason(null);
            updateById(songDTO);
        }

        return Result.success(true);
    }

    @Override
    public Result<SongVo> findById(Long id) {
        // 把歌词信息一并带出来
        Song song = songMapper.selectById(id);
        if (song == null) {
            return Result.error("歌曲不存在");
        }

        List<Lyrics> lyrics = lyricsMapper.selectList(
                new LambdaQueryWrapper<Lyrics>()
                        .eq(Lyrics::getSongId, id)
                        .orderByAsc(Lyrics::getTime)
        );
        // 查询用户信息
        User user = userMapper.selectById(song.getUserId());
        SongVo songVo = new SongVo();
        BeanUtil.copyProperties(song, songVo);
        songVo.setLyrics(lyrics);
        songVo.setUser(user);
        return Result.success(songVo);
    }

    @Override
    public Result<Void> report(Long songId) {
        // 每个用户只能举报reportCount次
        Long userId = UserContextUtil.getUserId();
        // 获取当前用户举报的次数
        Object objectValue = redisTemplate.opsForValue().get("report:" + userId);
        int redisReportCount = 0;
        if (objectValue != null) {
            redisReportCount = Integer.parseInt(objectValue.toString());
        }
        if (redisReportCount >= this.reportCount) {
            return Result.error("您在" + reportTimeOut + "天中已经举报过" + this.reportCount + "次了，不能再举报了");
        }
        // 直接将歌曲的状态改为待审核
        lambdaUpdate()
                .set(Song::getStatus, 0)
                .eq(Song::getId, songId)
                .update();
        // 举报次数+1
        redisTemplate.opsForValue().set("report:" + userId, redisReportCount + 1, reportTimeOut, TimeUnit.DAYS);
        return Result.successMsg("举报成功");
    }

}

